﻿using Shared.Method;
using Shared.Model;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Shared.SoftMethod
{
    //delegate void SetControlCallBack(Form form, Control con, string text, Color col);

    public class SoftShared
    {

        /// <summary>
        /// 设置临时MAC或临时SN
        /// </summary>
        /// <param name="tel"></param>
        /// <param name="message"></param>
        public static void SetTempMsg(YcdTelnetSecond tel, out string message)
        {
            //if (device.PONType == SharedData.EPON)
            //获取光猫类型
            //tel.Send("flash get PON_MODE");
            message = string.Empty;

            try
            {
                string msg = null;

                //bool ret = tel.GetReturnMsg("PON_MODE=", out msg);

                bool ret = tel.SendAndRecv("flash get PON_MODE", "PON_MODE=", out msg);

                message += msg;

                if (msg.Contains("=2"))
                {
                    tel.SendAndRecv("flash set EPON_LLID_TBL.0.macAddr 14E0:B0F1:9530::", "macAddr=14E0", out msg, 6000);
                }
                else if (msg.Contains("=1"))
                {
                    tel.SendAndRecv("flash set GPON_SN FHTT002460E2", "=FHTT002460E2", out msg, 6000);
                }
                else
                {
                    msg = "获取PON类型失败";
                }
                message += msg;
            }
            catch (Exception ex)
            {
                message += ex.ToString();
            }
        }

        #region 按键/语音/灯光测试

        //语音测试，返回true or false
        public static bool VoiceTest(YcdTelnetSecond tel, ContainerControl container, RichTextBox rich,  string keyWord = "MPtest")
        {
            bool recvResult = tel.SendAndRecv("voipmp", keyWord, out string outMsg, 5000);

            AppendText(container, rich, outMsg);

            if (outMsg.Contains("getHookState"))
            {
                AppendText(container, rich, "语音回显异常，不能测试语音功能");
                return false;
            }

            if (tel.SendAndRecv(string.Empty, "getHookState", out outMsg, 2000))
            {
                AppendText(container, rich, "语音回显异常，不能测试语音功能");
                return false;
            }

            if (recvResult == false)
            {
                AppendText(container, rich, "未能开启语音测试功能");
                return false;
            }
            else
            {
                AppendText(container, rich, "开启语音测试");
            }

            AppendText(container, rich, "你有30秒时拨打电话……");

            for (int i = 0; i < 20; i++)
            {
                if (recvResult = tel.SendAndRecv(null, "voip_factory_uninit: entry", out outMsg)) break;

                AppendText(container, rich, outMsg);
            }

            AppendText(container, rich, outMsg + "\r语音测试完成");

            return recvResult;
        }

        //USB测试
        public static bool UsbTest(YcdTelnetSecond tel, RichTextBox rich, ContainerControl container)
        {
            //判断tel是否连接着
            if (tel == null || tel.Connected == false)
            {
                AppendText(container, rich, "USB测试失败，传入参数错误");
                return false;
            }

            bool ret = false;

            string outMsg;

            //重试30次
            for (int i = 0; i < 30; i++)
            {
                ret = tel.SendAndRecv("usbmp", "success", out outMsg);
                AppendText(container, rich, outMsg);

                if (ret) break;
            }

            if (ret) AppendText(container, rich, "USB测试成功");
            else
            {
                AppendText(container, rich, "USB测试失败");
                return false;
            }

            return true;
        }

        //按键测试
        public static bool ButtonTest(YcdTelnetSecond tel, ContainerControl container, RichTextBox rich, Control control, string keywifi, string keyreset, string keywps = null)
        {
            //判断tel是否连接着
            if (tel == null || tel.Connected == false)
            {
                AppendText(container, rich, "按键测试失败，传入参数错误");
                return false;
            }

            bool ret = false;

            SetControl(container, control, "检查灯光,按WIFI按钮", Color.BlueViolet);

            //重试30次
            for (int i = 0; i < 20; i++)
            {
                ret = tel.SendAndRecv(null, keywifi, out string msg);

                AppendText(container, rich, msg);

                if (ret) break;
            }

            if (ret)
            {
                AppendText(container, rich, "WIFI按钮测试成功");
            }
            else
            {
                AppendText(container, rich, "WIFI按钮测试失败");
                return false;
            }

            //复位按钮
            SetControl(container, control, "按复位/LED按钮", Color.BlueViolet);

            //重试20次
            for (int i = 0; i < 20; i++)
            {
                ret = tel.SendAndRecv(null, keyreset, out string msg);

                AppendText(container, rich, msg);

                if (ret) break;
            }

            if (ret)
            {
                AppendText(container, rich, "复位按钮测试成功");

            }
            else
            {
                AppendText(container, rich, "复位按钮测试失败");
                return false;
            }

            if (string.IsNullOrEmpty(keywps)) return ret;

            //wps按键
            SetControl(container, control, "按WPS按键", Color.BlueViolet);

            //重试30次
            for (int i = 0; i < 20; i++)
            {
                ret = tel.SendAndRecv(null, keywps, out string msg);

                AppendText(container, rich, msg);

                if (ret) break;
            }

            if (ret)
            {
                AppendText(container, rich, "WPS按钮测试成功");
            }
            else
            {
                AppendText(container, rich, "WPS按钮测试失败");
                return false;
            }

            return true;
        }

        #endregion

        public static bool CheckWifiMsg(YcdTelnetSecond tel, out string message)
        {
            //执行命令获取数据
            message = string.Empty;
            //string key;
            if (tel.SendAndRecv("flash get HW_WLAN0_11N_XCAP", "HW_WLAN0_11N_XCAP=", out string msg))
            {
                //AppendRichTextBox(msg);
                message += msg;
                if (msg.Contains("HW_WLAN0_11N_XCAP=00")) return false;
            }
            else return false;

            if (tel.SendAndRecv("flash get HW_WLAN0_TX_POWER_CCK_A", "HW_WLAN0_TX_POWER_CCK_A=", out msg))
            {
                //AppendRichTextBox(msg);
                message += msg;
                if (msg.Contains("=0000000000000000000000000000")) return false;
                //key = "HW_WLAN0_TX_POWER_CCK_A" + msg.Substring(msg.IndexOf("="));
                //if (wifiMsg.Contains(key) == false) return false;
            }
            else return false;

            if (tel.SendAndRecv("flash get HW_WLAN0_TX_POWER_HT40_1S_A", "HW_WLAN0_TX_POWER_HT40_1S_A=", out msg))
            {
                //AppendRichTextBox(msg);
                message += msg;
                //key = "HW_WLAN0_TX_POWER_HT40_1S_A" + msg.Substring(msg.IndexOf("="));
                //if (wifiMsg.Contains(key) == false) return false;
                if (msg.Contains("=0000000000000000000000000000")) return false;
            }
            else return false;

            if (tel.SendAndRecv("flash get HW_WLAN0_TX_POWER_CCK_B", "HW_WLAN0_TX_POWER_CCK_B=", out msg))
            {
                //AppendRichTextBox(msg);
                message += msg;
                //key = "HW_WLAN0_TX_POWER_CCK_B" + msg.Substring(msg.IndexOf("="));
                //if (wifiMsg.Contains(key) == false) return false;
                if (msg.Contains("=0000000000000000000000000000")) return false;
            }
            else return false;

            if (tel.SendAndRecv("flash get HW_WLAN0_TX_POWER_HT40_1S_B", "HW_WLAN0_TX_POWER_HT40_1S_B=", out msg))
            {
                //AppendRichTextBox(msg);
                message += msg;
                //key = "HW_WLAN0_TX_POWER_HT40_1S_B" + msg.Substring(msg.IndexOf("="));
                //if (wifiMsg.Contains(key) == false) return false;
                if (msg.Contains("=0000000000000000000000000000")) return false;
            }
            else return false;

            /*2018年9月8日取消这两项WIFI检查
            if (tel.SendAndRecv("flash get HW_WLAN0_TX_POWER_DIFF_OFDM", "HW_WLAN0_TX_POWER_DIFF_OFDM=", out msg))
            {
                //AppendRichTextBox(msg);
                message += msg;
                //key = "HW_WLAN0_TX_POWER_DIFF_OFDM" + msg.Substring(msg.IndexOf("="));
                //if (wifiMsg.Contains(key) == false) return false;
                if (msg.Contains("=0000000000000000000000000000")) return false;
            }
            else return false;

            if (tel.SendAndRecv("flash get HW_WLAN0_TX_POWER_DIFF_HT20", "HW_WLAN0_TX_POWER_DIFF_HT20=", out msg))
            {
                //AppendRichTextBox(msg);
                message += msg;
                //key = "HW_WLAN0_TX_POWER_DIFF_HT20" + msg.Substring(msg.IndexOf("="));
                //if (wifiMsg.Contains(key) == false) return false;
                if (msg.Contains("=0000000000000000000000000000")) return false;
            }
            else return false;
            */

            if (tel.SendAndRecv("cat /proc/wlan0/mib_rf", "ther:", out msg))
            {
                //AppendRichTextBox(msg);
                message += msg;
                if (msg.Replace(" ", "").Contains("ther:0")) return false;
            }
            else return false;

            return true;
        }

        #region 登录移动光猫

        public static void LoginCMCC(string modemIp, string localip, int localPort, ref int localOffset, string province)
        {
            HttpArgs args = new HttpArgs()
            {
                Host = "192.168.1.1",
                Url = "/admin/login.asp",
                Port = 80
            };

            HttpBaseClass.GetHttpMsg(localip, localPort + localOffset++, modemIp, args.Port, args, "OK", out string oMsg, HttpBaseClass.HttpMethod.GET);
            //AppendRichTextBox(oMsg);
            //portOffset++;

            string pattern = @"csrfmiddlewaretoken.+/>";
            var match = Regex.Match(oMsg, pattern);
            if (match.Success == false) return;
            string csrftoken = match.Value.Substring(match.Value.IndexOf('=') + 2, 32);

            pattern = @"csrftoken.+/>";
            var match2 = Regex.Match(oMsg, pattern);
            if (match2.Success == false) return;
            string wareToken = match2.Value.Substring(match2.Value.IndexOf('=') + 2, 32);

            string user = "CMCCAdmin";
            string pwd = "aDm8H%MdA";

            if (province.Contains("GX"))
            {
                user = "admin";
                pwd = "Cmcc10086#";
            }

            args.Url = "/boaform/admin/formLogin";
            args.Host = "192.168.1.1";
            args.Body = string.Format("username2=user&psd2=&username1={0}&psd1={1}&csrfmiddlewaretoken={2}&username={0}&psd={1}&csrftoken={3}"
                , user
                , pwd
                , wareToken
                , csrftoken);

            HttpBaseClass.GetHttpMsg(localip, localPort + localOffset++, modemIp, args.Port, args, "OK", out oMsg, HttpBaseClass.HttpMethod.POST);

        }

        #endregion

        /// <summary>
        /// 重置光猫
        /// </summary>
        /// <param name="tel"></param>
        /// <param name="deviceType"></param>
        /// <param name="message"></param>
        public static bool ResetModem(YcdTelnetSecond tel, ModemType deviceType, out string message)
        {
            System.Threading.Thread.Sleep(1000);
            message = string.Empty;

            string msg;
            bool result;
            if (deviceType == ModemType.DX_924)
            {
                result = tel.SendAndRecv("flash default cs\r\n", "reboot", out msg, 15000);
            }
            else
            {
                result = tel.SendAndRecv("mp_default\r\n", "reboot", out msg, 15000);
            }

            //AppendRichTextBox(msg);
            message += msg;


            //result = tel.SendAndRecv("\r\n", "reboot", out msg, 6000);

            if (result == false)
            {
                message += "恢复出厂设置失败";
                return false;
            }

            //message += msg;

            if (deviceType != ModemType.YD_924)
            {
                tel.Send("reboot -f");

                message += "#reboot -f\r\n重置光猫开始……";
            }

            return true;
        }
        /// <summary>
        /// 设置颜色、内容
        /// </summary>
        /// <param name="form"></param>
        /// <param name="con"></param>
        /// <param name="text"></param>
        /// <param name="col"></param>
        public static void SetControl(Form form, Control con, string text, Color col = new Color())
        {
            if (form.InvokeRequired)
            {
                Action<Form, Control, string, Color> d = new Action<Form, Control, string, Color>(SetControl);
                form.Invoke(d, form, con, text, col);
            }
            else
            {
                con.Text = text;
                con.ForeColor = col;
            }
        }

        public static void SetControl(ContainerControl container, Control con, string text, Color col = new Color())
        {
            if (container.InvokeRequired)
            {
                Action<ContainerControl, Control, string, Color> d = new Action<ContainerControl, Control, string, Color>(SetControl);
                container.Invoke(d, container, con, text, col);
            }
            else
            {
                con.Text = text;
                con.ForeColor = col;
            }
        }

        public static void SetControl(UserControl userCtl, Control con, string text, Color col = new Color())
        {
            if (userCtl.InvokeRequired)
            {
                Action<UserControl, Control, string, Color> d = new Action<UserControl, Control, string, Color>(SetControl);
                userCtl.Invoke(d, userCtl, con, text, col);
            }
            else
            {
                con.Text = text;
                con.ForeColor = col;
            }
        }

        /// <summary>
        /// 设置对象是否可用
        /// </summary>
        /// <param name="form"></param>
        /// <param name="con"></param>
        /// <param name="able"></param>
        public static void SetControlEnable(Form form, Control con, bool able = true)
        {
            if (form.InvokeRequired)
            {
                Action<Form, Control, bool> d = new Action<Form, Control, bool>(SetControlEnable);
                form.Invoke(d, form, con, able);
            }
            else
            {
                con.Enabled = able;
            }
        }
        /// <summary>
        /// 设置对象是否可读
        /// </summary>
        /// <param name="form"></param>
        /// <param name="box"></param>
        /// <param name="readOnly"></param>
        public static void SetTextBoxReadOnly(Form form, TextBoxBase box, bool readOnly = false)
        {
            if (form.InvokeRequired)
            {
                Action<Form, TextBoxBase, bool> d = new Action<Form, TextBoxBase, bool>(SetTextBoxReadOnly);
                form.Invoke(d, form, box, readOnly);
            }
            else
            {
                box.ReadOnly = readOnly;
            }
        }
        /// <summary>
        /// 新增内容
        /// </summary>
        /// <param name="form"></param>
        /// <param name="box"></param>
        /// <param name="text"></param>
        //public static void AppendText(Form form, RichTextBox box, string text)
        //{
        //    if (string.IsNullOrEmpty(text)) return;

        //    if (form.InvokeRequired)
        //    {
        //        Action<Form, RichTextBox, string> d = new Action<Form, RichTextBox, string>(AppendText);
        //        form.Invoke(d, form, box, text);
        //    }
        //    else
        //    {
        //        text = text.Replace("\0", "");
        //        box.AppendText(text + "\r\n");
        //    }
        //}

        //public static void AppendText(UserControl ctl, RichTextBox box, string text)
        //{
        //    if (string.IsNullOrEmpty(text)) return;

        //    if (ctl.InvokeRequired)
        //    {
        //        Action<UserControl, RichTextBox, string> d = new Action<UserControl, RichTextBox, string>(AppendText);
        //        ctl.Invoke(d, ctl, box, text);
        //    }
        //    else
        //    {
        //        text = text.Replace("\0", "");
        //        box.AppendText(text + "\r\n");
        //    }
        //}

        public static void AppendText(ContainerControl container, RichTextBox box, string text)
        {
            if (string.IsNullOrEmpty(text)) return;

            if (container.InvokeRequired)
            {
                Action<ContainerControl, RichTextBox, string> d = new Action<ContainerControl, RichTextBox, string>(AppendText);
                container.Invoke(d, container, box, text);
            }
            else
            {
                text = text.Replace("\0", "");
                box.AppendText(text + "\r\n");
            }
        }

        public static void AppendText(ContainerControl container, RichTextBox box, string text, ref string log)
        {
            if (string.IsNullOrEmpty(text)) return;

            log += $"{text}\r\n";

            if (container.InvokeRequired)
            {
                Action<ContainerControl, RichTextBox, string> d = new Action<ContainerControl, RichTextBox, string>(AppendText);
                container.Invoke(d, container, box, text);
            }
        }

    }
}
